This page last changed on Jul 03, 2007 by scytacki.

OTrunk uses ids to look up and store references to objects. The root class of this system is an empty interface called OTID. This interface is implemented by:
OTPathID, OTRelativeID, and OTUUID.

A user of the OTrunk system shouldn't have to worry about these different types of IDs, but there are a few places where they show up.
The current xml representation of OTrunk otml, uses something called a local_id which is the most widely used way to reference objects. The original intention was for local_id to only be valid within a particualar otml file. And global_ids all be UUIDs and to be valid across multiple files. However as the system has grown this has been blurred a bit.

In the current system most people have used local_ids in their otml files. Most of these ids are handled when the document is loaded. They are replaced with: (otml UUID)!/(local_id). So for example a object with a local_id like this:

<OTUDLQuestion local_id="udl_question_1">

While get converted and when it is saved again it will look like this:

<OTUDLQuestion id="33754150-b594-11d9-9669-0800200c9a66!/udl_question_1">

The UUID was taken from the otrunk element of the initial document.

local_ids are referenced again using a syntax:

${(local_id)}

OTUUID - provides a OTID implementation that uses a UUID for the id of the object. Currently when a new OTObject instance is created in the Java code a new OTUUID is created for that object. OTUUID's are strongly encouraged for each otml file which is created, this id is specified in the otrunk element at the root of the document. Something like this:

<otrunk id="33754150-b594-11d9-9669-0800200c9a66" >

OTRelativeID - provides a way to reference an id relative to another id. This class has a rootId and a relativeId. It is typically used to store the local_id style ids above. So the local_id is relative to the root id of the otml file. When this id is written out the "!" character is placed between the root and relative ids.

OTPathID - this id is used by the current xml representation to store an id based on the path to the object in the document. So if you create an OTObject in a otml file which doesn't have a local or global id then a path id is used. The path id is based on the location of this OTObject in the otml file. An example of a PathID is:

33754150-b594-11d9-9669-0800200c9a66/services[0]/modes[1]/map['${compound_doc_view}']

The path is divided by the "/" characters. This id illustrates several parts of the path ids. The first element is an object with an id attribute set to a UUID. The next element says this points to the first service in the services feature/property of the first element. The next points to the second mode in the modes feature/property of the service. The next points to the map entry which has the key:

 ${compound_doc_view} 

Adding a new OTDatabase with a different id system

A new OTDatabase might work best with a different ID design.
Currently the main hinderence to this is the method:
OTIDFactory.createOTID(String idStr)

The problem with this is that it means the OTIDFactory needs to know about this new ID system. That method has been hidden behind 2 layers of abstraction, so it should be possible to work with those layers to support multiple ID system. However the OTIDFactory.createOTID method is still called in 11 places, however all of those places are internal to the OTrunk system so they are under our control.

The first abstracted way of getting an id is to use the OTrunk method getOTID(String id).
That method is used only in 3 places:

  • the object service impl which is the next abstraction layer
  • 2 times in the sync4j code which is not used anymore.
    The sync4j code can be hacked to fit whatever we come up with.

The second abstraction is the OTObjectService method getOTID(String id). This is used in 4 places:

  • 2 in the DefaultOTObject code to implement the methods getReferencedId and getReferencedObject
  • 1 in the OTrunkUtil method getObjectFromMapWithIdKeys, this is a helper when you need to create maps that have keys were are the ids of objects.
  • 1 in AbstractOTDocumentView to implement getReferencedObject

So the issue that needs to be dealt with is how the OT system can identify which data storage library should convert an id string to an actually OTID. It might work to say that an OTObjectService has to be associated with a particular data storage library. The OTObjectService already had 2 databases the creationDb and the mainDb. Each of these could be a different type of database. It seems the safest approach would be to require that the call of the method needs to also pass in the OTObject that is making this string based id reference. Then the database of that object can be looked up and it can be used to create the id. Even this could still be a problem in the case of overlayed object, like the user object. The overlaying object might be in one type of the database and the underlying object in another type. In this case simplying having the OTObject is not enough. The system would need to know the property of the object, to see which database that property comes from for this particular object.

Another alternative is to remove ids entirely from being used as strings within properties. There are 2 cases that need to be dealt with here:

  • documents with references and links
    • this can be handled by turning all the references into indexed references from a list inside of the document. For backward compatibility this can be done
      when the document is being loaded. And if it becomes a pain to uses lists like these then the objects can be remapped to ids automatically as they are written out. This approach would probably work the best if the way the ids were referenced in the document was with a string not an index. This will make it easier to maintain. But this will make referencing an object harder in a document. If the document loader and writer could do it automatically that would be the best, but that makes it more difficult to write crossplatform libraries for processing this stuff. If someone adds a new type that does this type of thing, all of the libraries for processing it will have to be updated to handle that type.
    • perhaps an approach is to separate the authored format from the portable format. When authoring you use the easy to write approach, and then before commiting it to a repository, you convert it to the portable format so it can be processed.
    • another alternative is to have a way for the portable schema to specify a pattern for finding references to other objects. I think that is probably not a good approach.
    • The best seems to be the object map with an automatic conversion process for now.
  • maps which use the id as a key.
    • the maps can be special cases so there is a special type of mape that works with objects instead of strings.

If we do all of these changes then it will simplify the copying code, and database implementations. The OTID string issue will go away.
OTrunk Plan to remove id strings

The tough case here is when copying from one data store to another. Currently this type of copying happens below the level of the OTObjectService.

Document generated by Confluence on Jan 27, 2014 16:52